package com.github.cosycode.imgtool.tool;

import com.github.cosycode.common.ext.bean.DoubleBean;
import com.github.cosycode.common.util.common.StrUtils;
import com.github.cosycode.common.util.io.IoUtils;
import lombok.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;

/**
 * <b>Description : </b>
 * <p>
 * <b>created in </b> 2022/5/15
 * </p>
 *
 * @author CPF
 * @since 1.0
 **/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TxtFileFormatterTool {

    /**
     * 按照规则进行替换
     *
     * @param txtFile     可以读取的文本文件
     * @param formatRules 格式化规则
     * @return FormatHandle 对象
     * @throws IOException 文件无法读取则抛出异常
     */
    public static FormatHandle doChangeBefore(@NonNull File txtFile, @NonNull FormatRule[] formatRules) throws IOException {
        String content = IoUtils.readFile(txtFile);
        // 记录处理信息
        FormatHandle formatRecord = new FormatHandle();
        for (FormatRule formatRule : formatRules) {
            formatRecord.addFormatRule(formatRule);
            final UnaryOperator<String> dispose = formatRule.getMatchDispose();
            content = StrUtils.replaceAll(formatRule.getMatchRegex(), content, originalStr -> {
                final String newStr = dispose.apply(originalStr);
                // 结果为 null 表示不进行替换处理, 依然是原来的字符串
                if (newStr == null) {
                    return originalStr;
                }
                formatRecord.addDisposeLog(originalStr, newStr);
                return newStr;
            });
        }
        formatRecord.setNewContent(content);
        return formatRecord;
    }

    /**
     * <b>Description : </b>
     * <p>
     * <b>created in </b> 2022/5/15
     * </p>
     *
     * @author CPF
     * @since 1.0
     **/
    @Getter
    @ToString
    @AllArgsConstructor
    public static class FormatRule {
        /**
         * 搜索字符串
         */
        private final String matchRegex;

        /**
         * 处理字符串函数(传入匹配到的字符串, 输出替代的字符串),
         * 输出 EMPTY_STRING, 表示删除原来内容
         * 输出 null, 表示不进行替换, 依然传入原来内容
         */
        private final UnaryOperator<String> matchDispose;
    }

    /**
     * <b>Description : </b>
     * <p>
     * <b>created in </b> 2022/5/15
     * </p>
     *
     * @author CPF
     * @since 1.0
     **/
    @Data
    public static class FormatHandle {

        /**
         * 处理的文本文件
         */
        private File txtFile;

        /**
         * 处理文本文件的规则
         */
        private List<FormatRule> formatRuleList;

        /**
         * 替换日志记录
         */
        private List<DoubleBean<String, String>> disposeLogList;

        /**
         * 文本新内容
         */
        private String newContent;

        public void addFormatRule(FormatRule formatRule) {
            if (formatRuleList == null) {
                formatRuleList = new ArrayList<>(4);
            }
            formatRuleList.add(formatRule);
        }

        public void addDisposeLog(String originalString, String newString) {
            if (formatRuleList == null) {
                disposeLogList = new ArrayList<>(10);
            }
            disposeLogList.add(DoubleBean.of(originalString, newString));
        }

    }

}
